#include<string>
#include<map>
#include<iostream>
#include<string.h>
#include"ConfigReader.h"
ConfigReader configReader;


ConfigReader::ConfigReader() {}

void ConfigReader::readCmd(int argc, const char * argv[]) {
    for (int i = 1; i < argc; i++) {
        if (argv[i][0] == '-') {
            switch (argv[i][1]) {
                case 'c': 
                    if (++i == argc) {
                        std::cerr << "Lost option -c value " << std::endl; exit(1);
                    }
                    this->cmdMap[CMD_PARAM_CONFIG_FILE] = std::string(argv[i]);
                    break;
                default:
                    std::cerr << "Unknow option:" << argv[i] << std::endl; exit(1);
                    break;
            }
        }
    }
    
}

std::string ConfigReader::getCmdParam(int key, std::string default_v) {
    if (this->cmdMap.count(key) == 1) {
        return this->cmdMap[key];
    } else {
        return default_v;
    }
}

void ConfigReader::loadConfigFile() {
    std::string filePath = this->getCmdParam(CMD_PARAM_CONFIG_FILE, "config.conf");
    std::cout << "Loading configure file from: " << filePath << std::endl;
    FILE * file = fopen(filePath.c_str(), "r");
    if ( file == NULL ) {
        std::cerr << "config.conf read failed: " << strerror(errno) <<std::endl;
        return;
    }

    char buffer[1024] = {0};
    std::string lineStr,key,value;
    int pos,line=0;
    while ( !feof(file) ) {
        line++;
        memset(buffer, 0, 1024);
        fgets(buffer, 1023, file);
        lineStr = std::string(buffer);
        if (lineStr[0] == '#' || lineStr[0] == '\n' || lineStr[0] == 0) {
            continue;
        }
        pos = lineStr.find('=');
        if (pos == -1) {
            fprintf(stderr, "[line:%d]Unknow configure option:%s\n", line, lineStr.c_str());
            continue;
        }
        key = lineStr.substr(0, pos);
        value = lineStr.substr(pos+1);
        if (value[value.length() - 1] == '\n') {
            value.pop_back();
        }
        this->configMap[key] = value;
    }
    

    fclose(file);
}

ConfigReader* ConfigReader::setConfig(std::string key, std::string value) {
    this->configMap[key] = value;
    return this;
}


void ConfigReader::printConfig() {
    for (auto i = this->configMap.begin(); i != this->configMap.end(); i++) {
        printf("%-20s\t:%s\n", i->first.c_str(), i->second.c_str());
        // std::cout << i->first << "\t:\t" << i->second << std::endl;
    }
}

std::string ConfigReader::getConfig(std::string key) {
    return this->getConfig(key, nullptr);
}
std::string ConfigReader::getConfig(std::string key, std::string default_value) {
    if (this->configMap.count(key) == 1) {
        return this->configMap[key];
    } else {
        return default_value;
    }
}
